package com.todo.pro.handle.audit.log;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
import com.alibaba.druid.sql.parser.SQLStatementParser;
import com.todo.pro.auditlog.handler.AbstractSQLAuditHandler;
import com.todo.pro.auditlog.handler.DBMetaDataHolder;

public class MySqlInsertSQLAuditHandler extends AbstractSQLAuditHandler {

	private Logger logger = LoggerFactory.getLogger(MySqlInsertSQLAuditHandler.class);

	private String table;

	private List<String> columnList = new ArrayList<>();

	private Boolean preHandled = Boolean.FALSE;

	public MySqlInsertSQLAuditHandler(Connection connection, DBMetaDataHolder dbMetaDataHolder, String insertSQL) {
		super(connection, dbMetaDataHolder, insertSQL);
	}

	@Override
	protected SQLStatement parseSQLStatement(SQLStatementParser statementParser) {
		return statementParser.parseInsert();
	}

	@Override
	protected SQLTableSource getMajorTableSource(SQLStatement statement) {
		if (statement instanceof MySqlInsertStatement)
			return ((MySqlInsertStatement) statement).getTableSource();
		else
			return null;
	}

	@Override
	public void preHandle() {
		if (getSqlStatement() instanceof MySqlInsertStatement) {
			MySqlInsertStatement sqlInsertStatement = (MySqlInsertStatement) getSqlStatement();
			if (sqlInsertStatement.getColumns().size() > 0) {
				SQLExpr sqlExpr = sqlInsertStatement.getColumns().get(0);
				String[] aliasAndColumn = separateAliasAndColumn(SQLUtils.toMySqlString(sqlExpr));
				if (aliasAndColumn[0] != null) {
					table = getAliasToTableMap().get(aliasAndColumn[0]);
				} else if (getTables().size() == 1) {
					table = getTables().get(0);
				} else {
					table = determineTableForColumn(aliasAndColumn[1]);
				}
				for (int i = 0; i < sqlInsertStatement.getColumns().size(); i++) {
					SQLExpr columnExpr = sqlInsertStatement.getColumns().get(i);
					columnList.add(separateAliasAndColumn(SQLUtils.toMySqlString(columnExpr))[1]);
				}
			}
			preHandled = Boolean.TRUE;
		}
	}

	@Override
	public void postHandle() {
		if (preHandled) {
			String row = "";
			if (columnList != null && columnList.size() > 0) {
				row = String.join(",", columnList);
			}
			logger.info("table: {}, insert one row {}", table, row);
		}
	}

}
